{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import io\n",
    "from surprise import KNNBaseline\n",
    "from surprise import Dataset\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import logging\n",
    "\n",
    "logging.basicConfig(level=logging.INFO,\n",
    "                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',\n",
    "                    datefmt='%a, %d %b %Y %H:%M:%S')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\evaluate.py:66: UserWarning: The evaluate() method is deprecated. Please use model_selection.cross_validate() instead.\n",
      "  'model_selection.cross_validate() instead.', UserWarning)\n",
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\dataset.py:193: UserWarning: Using data.split() or using load_from_folds() without using a CV iterator is now deprecated. \n",
      "  UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluating RMSE, MAE of algorithm SVD.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "RMSE: 0.9478\n",
      "MAE:  0.7475\n",
      "------------\n",
      "Fold 2\n",
      "RMSE: 0.9430\n",
      "MAE:  0.7445\n",
      "------------\n",
      "Fold 3\n",
      "RMSE: 0.9422\n",
      "MAE:  0.7430\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9444\n",
      "Mean MAE : 0.7450\n",
      "------------\n",
      "------------\n",
      "        Fold 1  Fold 2  Fold 3  Mean    \n",
      "RMSE    0.9478  0.9430  0.9422  0.9444  \n",
      "MAE     0.7475  0.7445  0.7430  0.7450  \n"
     ]
    }
   ],
   "source": [
    "# 可以使用上面提到的各种推荐系统算法\n",
    "from surprise import SVD\n",
    "from surprise import Dataset\n",
    "from surprise import evaluate, print_perf\n",
    "\n",
    "# 默认载入movielens数据集，会提示是否下载这个数据集，这是非常经典的公开推荐系统数据集——MovieLens数据集之一\n",
    "data = Dataset.load_builtin('ml-100k')\n",
    "# k折交叉验证(k=3)\n",
    "data.split(n_folds=3)\n",
    "# 试一把SVD矩阵分解\n",
    "algo = SVD()\n",
    "# 在数据集上测试一下效果\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "#输出结果\n",
    "print_perf(perf)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "算法调参(让推荐系统有更好的效果)\n",
    "这里实现的算法用到的算法无外乎也是SGD等，因此也有一些超参数会影响最后的结果，我们同样可以用sklearn中常用到的网格搜索交叉验证(GridSearchCV)来选择最优的参数。简单的例子如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\evaluate.py:232: UserWarning: The GridSearch() class is deprecated. Please use model_selection.GridSearchCV instead.\n",
      "  'model_selection.GridSearchCV instead.', UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running grid search for the following parameter combinations:\n",
      "{'n_epochs': 5, 'lr_all': 0.002, 'reg_all': 0.4}\n",
      "{'n_epochs': 5, 'lr_all': 0.002, 'reg_all': 0.6}\n",
      "{'n_epochs': 5, 'lr_all': 0.005, 'reg_all': 0.4}\n",
      "{'n_epochs': 5, 'lr_all': 0.005, 'reg_all': 0.6}\n",
      "{'n_epochs': 10, 'lr_all': 0.002, 'reg_all': 0.4}\n",
      "{'n_epochs': 10, 'lr_all': 0.002, 'reg_all': 0.6}\n",
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}\n",
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.6}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\evaluate.py:66: UserWarning: The evaluate() method is deprecated. Please use model_selection.cross_validate() instead.\n",
      "  'model_selection.cross_validate() instead.', UserWarning)\n",
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\dataset.py:193: UserWarning: Using data.split() or using load_from_folds() without using a CV iterator is now deprecated. \n",
      "  UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Resulsts:\n",
      "{'n_epochs': 5, 'lr_all': 0.002, 'reg_all': 0.4}\n",
      "{'RMSE': 0.99757802895975123, 'FCP': 0.68344528462992526}\n",
      "----------\n",
      "{'n_epochs': 5, 'lr_all': 0.002, 'reg_all': 0.6}\n",
      "{'RMSE': 1.0034412513430804, 'FCP': 0.68687609151250051}\n",
      "----------\n",
      "{'n_epochs': 5, 'lr_all': 0.005, 'reg_all': 0.4}\n",
      "{'RMSE': 0.97430396591083557, 'FCP': 0.69267116521887429}\n",
      "----------\n",
      "{'n_epochs': 5, 'lr_all': 0.005, 'reg_all': 0.6}\n",
      "{'RMSE': 0.98306874054929827, 'FCP': 0.69355288039671981}\n",
      "----------\n",
      "{'n_epochs': 10, 'lr_all': 0.002, 'reg_all': 0.4}\n",
      "{'RMSE': 0.97845027003242768, 'FCP': 0.69177462351387298}\n",
      "----------\n",
      "{'n_epochs': 10, 'lr_all': 0.002, 'reg_all': 0.6}\n",
      "{'RMSE': 0.98654376832754365, 'FCP': 0.69286994997251039}\n",
      "----------\n",
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}\n",
      "{'RMSE': 0.96436411806250799, 'FCP': 0.69717746370739053}\n",
      "----------\n",
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.6}\n",
      "{'RMSE': 0.97412101384387262, 'FCP': 0.69751300786180559}\n",
      "----------\n",
      "0.964364118063\n",
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}\n",
      "0.697513007862\n",
      "{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.6}\n"
     ]
    }
   ],
   "source": [
    "from surprise import GridSearch\n",
    "# 定义好需要优选的参数网格\n",
    "param_grid = {'n_epochs': [5, 10], 'lr_all': [0.002, 0.005],\n",
    "              'reg_all': [0.4, 0.6]}\n",
    "# 使用网格搜索交叉验证\n",
    "grid_search = GridSearch(SVD, param_grid, measures=['RMSE', 'FCP'])\n",
    "# 在数据集上找到最好的参数\n",
    "data = Dataset.load_builtin('ml-100k')\n",
    "data.split(n_folds=3)\n",
    "grid_search.evaluate(data)\n",
    "# 输出调优的参数组 \n",
    "# 输出最好的RMSE结果\n",
    "print(grid_search.best_score['RMSE'])\n",
    "# >>> 0.96117566386\n",
    "\n",
    "# 输出对应最好的RMSE结果的参数\n",
    "print(grid_search.best_params['RMSE'])\n",
    "# >>> {'reg_all': 0.4, 'lr_all': 0.005, 'n_epochs': 10}\n",
    "\n",
    "# 最好的FCP得分\n",
    "print(grid_search.best_score['FCP'])\n",
    "# >>> 0.702279736531\n",
    "\n",
    "# 对应最高FCP得分的参数\n",
    "print(grid_search.best_params['FCP'])\n",
    "# >>> {'reg_all': 0.6, 'lr_all': 0.005, 'n_epochs': 10}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用不同的推荐系统算法进行建模比较"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\evaluate.py:66: UserWarning: The evaluate() method is deprecated. Please use model_selection.cross_validate() instead.\n",
      "  'model_selection.cross_validate() instead.', UserWarning)\n",
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\dataset.py:193: UserWarning: Using data.split() or using load_from_folds() without using a CV iterator is now deprecated. \n",
      "  UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluating RMSE, MAE of algorithm NormalPredictor.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "RMSE: 1.5225\n",
      "MAE:  1.2223\n",
      "------------\n",
      "Fold 2\n",
      "RMSE: 1.5231\n",
      "MAE:  1.2261\n",
      "------------\n",
      "Fold 3\n",
      "RMSE: 1.5139\n",
      "MAE:  1.2174\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 1.5198\n",
      "Mean MAE : 1.2220\n",
      "------------\n",
      "------------\n",
      "Evaluating RMSE, MAE of algorithm BaselineOnly.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "Estimating biases using als...\n",
      "RMSE: 0.9504\n",
      "MAE:  0.7544\n",
      "------------\n",
      "Fold 2\n",
      "Estimating biases using als...\n",
      "RMSE: 0.9476\n",
      "MAE:  0.7515\n",
      "------------\n",
      "Fold 3\n",
      "Estimating biases using als...\n",
      "RMSE: 0.9445\n",
      "MAE:  0.7487\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9475\n",
      "Mean MAE : 0.7515\n",
      "------------\n",
      "------------\n",
      "Evaluating RMSE, MAE of algorithm KNNBasic.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9894\n",
      "MAE:  0.7818\n",
      "------------\n",
      "Fold 2\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9907\n",
      "MAE:  0.7828\n",
      "------------\n",
      "Fold 3\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9867\n",
      "MAE:  0.7800\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9889\n",
      "Mean MAE : 0.7815\n",
      "------------\n",
      "------------\n",
      "Evaluating RMSE, MAE of algorithm KNNWithMeans.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9563\n",
      "MAE:  0.7540\n",
      "------------\n",
      "Fold 2\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9568\n",
      "MAE:  0.7541\n",
      "------------\n",
      "Fold 3\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9569\n",
      "MAE:  0.7533\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9567\n",
      "Mean MAE : 0.7538\n",
      "------------\n",
      "------------\n",
      "Evaluating RMSE, MAE of algorithm KNNBaseline.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "Estimating biases using als...\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9373\n",
      "MAE:  0.7394\n",
      "------------\n",
      "Fold 2\n",
      "Estimating biases using als...\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9368\n",
      "MAE:  0.7383\n",
      "------------\n",
      "Fold 3\n",
      "Estimating biases using als...\n",
      "Computing the msd similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "RMSE: 0.9358\n",
      "MAE:  0.7367\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9367\n",
      "Mean MAE : 0.7381\n",
      "------------\n",
      "------------\n",
      "Evaluating RMSE, MAE of algorithm SVD.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "RMSE: 0.9464\n",
      "MAE:  0.7476\n",
      "------------\n",
      "Fold 2\n",
      "RMSE: 0.9458\n",
      "MAE:  0.7459\n",
      "------------\n",
      "Fold 3\n",
      "RMSE: 0.9423\n",
      "MAE:  0.7434\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9448\n",
      "Mean MAE : 0.7456\n",
      "------------\n",
      "------------\n",
      "Evaluating RMSE, MAE of algorithm SVDpp.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "RMSE: 0.9292\n",
      "MAE:  0.7305\n",
      "------------\n",
      "Fold 2\n",
      "RMSE: 0.9273\n",
      "MAE:  0.7287\n",
      "------------\n",
      "Fold 3\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-17-4c09ee3f9aec>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     32\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msurprise\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mSVDpp\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mevaluate\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     33\u001b[0m \u001b[0malgo\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mSVDpp\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 34\u001b[1;33m \u001b[0mperf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mevaluate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0malgo\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmeasures\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'RMSE'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'MAE'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     35\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     36\u001b[0m \u001b[1;31m### 使用NMF\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\evaluate.py\u001b[0m in \u001b[0;36mevaluate\u001b[1;34m(algo, data, measures, with_dump, dump_dir, verbose)\u001b[0m\n\u001b[0;32m     81\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     82\u001b[0m         \u001b[1;31m# train and test algorithm. Keep all rating predictions in a list\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 83\u001b[1;33m         \u001b[0malgo\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtrainset\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     84\u001b[0m         \u001b[0mpredictions\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0malgo\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtest\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtestset\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mverbose\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mverbose\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     85\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m~\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\prediction_algorithms\\matrix_factorization.pyx\u001b[0m in \u001b[0;36msurprise.prediction_algorithms.matrix_factorization.SVDpp.fit\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;32m~\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\prediction_algorithms\\matrix_factorization.pyx\u001b[0m in \u001b[0;36msurprise.prediction_algorithms.matrix_factorization.SVDpp.sgd\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;32m~\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\trainset.py\u001b[0m in \u001b[0;36mall_ratings\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m    188\u001b[0m         \u001b[1;32mfor\u001b[0m \u001b[0mu\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mu_ratings\u001b[0m \u001b[1;32min\u001b[0m \u001b[0miteritems\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mur\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    189\u001b[0m             \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mr\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mu_ratings\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 190\u001b[1;33m                 \u001b[1;32myield\u001b[0m \u001b[0mu\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mr\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    191\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    192\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0mbuild_testset\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "### 使用NormalPredictor\n",
    "from surprise import NormalPredictor, evaluate\n",
    "algo = NormalPredictor()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用BaselineOnly\n",
    "from surprise import BaselineOnly, evaluate\n",
    "algo = BaselineOnly()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用基础版协同过滤\n",
    "from surprise import KNNBasic, evaluate\n",
    "algo = KNNBasic()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用均值协同过滤\n",
    "from surprise import KNNWithMeans, evaluate\n",
    "algo = KNNWithMeans()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用协同过滤baseline\n",
    "from surprise import KNNBaseline, evaluate\n",
    "algo = KNNBaseline()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用SVD\n",
    "from surprise import SVD, evaluate\n",
    "algo = SVD()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用SVD++\n",
    "from surprise import SVDpp, evaluate\n",
    "algo = SVDpp()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "\n",
    "### 使用NMF\n",
    "from surprise import NMF\n",
    "algo = NMF()\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "print_perf(perf)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用协同过滤构建模型并进行预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\evaluate.py:66: UserWarning: The evaluate() method is deprecated. Please use model_selection.cross_validate() instead.\n",
      "  'model_selection.cross_validate() instead.', UserWarning)\n",
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\dataset.py:193: UserWarning: Using data.split() or using load_from_folds() without using a CV iterator is now deprecated. \n",
      "  UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluating RMSE, MAE of algorithm SVD.\n",
      "\n",
      "------------\n",
      "Fold 1\n",
      "RMSE: 0.9439\n",
      "MAE:  0.7449\n",
      "------------\n",
      "Fold 2\n",
      "RMSE: 0.9455\n",
      "MAE:  0.7462\n",
      "------------\n",
      "Fold 3\n",
      "RMSE: 0.9467\n",
      "MAE:  0.7460\n",
      "------------\n",
      "------------\n",
      "Mean RMSE: 0.9454\n",
      "Mean MAE : 0.7457\n",
      "------------\n",
      "------------\n",
      "        Fold 1  Fold 2  Fold 3  Mean    \n",
      "RMSE    0.9439  0.9455  0.9467  0.9454  \n",
      "MAE     0.7449  0.7462  0.7460  0.7457  \n"
     ]
    }
   ],
   "source": [
    "# 可以使用上面提到的各种推荐系统算法\n",
    "from surprise import SVD\n",
    "from surprise import Dataset\n",
    "from surprise import evaluate, print_perf\n",
    "\n",
    "# 默认载入movielens数据集\n",
    "data = Dataset.load_builtin('ml-100k')\n",
    "# k折交叉验证(k=3)\n",
    "data.split(n_folds=3)\n",
    "# 试一把SVD矩阵分解\n",
    "algo = SVD()\n",
    "# 在数据集上测试一下效果\n",
    "perf = evaluate(algo, data, measures=['RMSE', 'MAE'])\n",
    "#输出结果\n",
    "print_perf(perf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from __future__ import (absolute_import, division, print_function,\n",
    "                        unicode_literals)\n",
    "import os\n",
    "import io\n",
    "\n",
    "from surprise import KNNBaseline\n",
    "from surprise import Dataset\n",
    "\n",
    "\n",
    "def read_item_names():\n",
    "    \"\"\"\n",
    "    获取电影名到电影id 和 电影id到电影名的映射\n",
    "    \"\"\"\n",
    "\n",
    "    file_name = (os.path.expanduser('~') +\n",
    "                 '/.surprise_data/ml-100k/ml-100k/u.item')\n",
    "    rid_to_name = {}\n",
    "    name_to_rid = {}\n",
    "    with io.open(file_name, 'r', encoding='ISO-8859-1') as f:\n",
    "        for line in f:\n",
    "            line = line.split('|')\n",
    "            rid_to_name[line[0]] = line[1]\n",
    "            name_to_rid[line[1]] = line[0]\n",
    "\n",
    "    return rid_to_name, name_to_rid\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jiangpin\\AppData\\Roaming\\Python\\Python36\\site-packages\\surprise\\prediction_algorithms\\algo_base.py:51: UserWarning: train() is deprecated. Use fit() instead\n",
      "  warnings.warn('train() is deprecated. Use fit() instead', UserWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Estimating biases using als...\n",
      "Computing the pearson_baseline similarity matrix...\n",
      "Done computing similarity matrix.\n",
      "\n",
      "和该电影最相似的前10部电影是:\n",
      "Lion King, The (1994)\n",
      "Toy Story (1995)\n",
      "Cinderella (1950)\n",
      "Hunchback of Notre Dame, The (1996)\n",
      "Sound of Music, The (1965)\n",
      "Clueless (1995)\n",
      "Aladdin (1992)\n",
      "E.T. the Extra-Terrestrial (1982)\n",
      "Winnie the Pooh and the Blustery Day (1968)\n",
      "Ghost (1990)\n"
     ]
    }
   ],
   "source": [
    "# 首先，用算法计算相互间的相似度\n",
    "data = Dataset.load_builtin('ml-100k')\n",
    "trainset = data.build_full_trainset()\n",
    "sim_options = {'name': 'pearson_baseline', 'user_based': False}\n",
    "algo = KNNBaseline(sim_options=sim_options)\n",
    "algo.train(trainset)\n",
    "\n",
    "# 获取电影名到电影id 和 电影id到电影名的映射\n",
    "rid_to_name, name_to_rid = read_item_names()\n",
    "\n",
    "# Retieve inner id of the movie Toy Story\n",
    "toy_story_raw_id = name_to_rid['Beauty and the Beast (1991)']\n",
    "toy_story_inner_id = algo.trainset.to_inner_iid(toy_story_raw_id)\n",
    "\n",
    "# Retrieve inner ids of the nearest neighbors of Toy Story.\n",
    "toy_story_neighbors = algo.get_neighbors(toy_story_inner_id, k=10)\n",
    "\n",
    "# Convert inner ids of the neighbors into names.\n",
    "toy_story_neighbors = (algo.trainset.to_raw_iid(inner_id)\n",
    "                       for inner_id in toy_story_neighbors)\n",
    "toy_story_neighbors = (rid_to_name[rid]\n",
    "                       for rid in toy_story_neighbors)\n",
    "\n",
    "print()\n",
    "print('和该电影最相似的前10部电影是:')\n",
    "for movie in toy_story_neighbors:\n",
    "    print(movie)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
